package com.ermax.aircond.common.dao;

import java.util.Iterator;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.Conjunction;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Disjunction;
import org.hibernate.criterion.Restrictions;
import org.hibernate.sql.JoinType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;

import com.ermax.aircond.common.domain.UserDetail;
import com.ermax.aircond.common.domain.UserGroup;
import com.ermax.aircond.util.dao.AbstractHibernateDao;

@Repository("userDetailDao")
public class UserDetailDao extends AbstractHibernateDao<UserDetail> implements java.io.Serializable{

	private static final Logger logger = LoggerFactory.getLogger(UserDetailDao.class);
	
	private static final long serialVersionUID = 1L;
	
	public UserDetailDao(){
		setClazz(UserDetail.class);
	}
	
	@SuppressWarnings("unchecked")
	public UserDetail findUserDetailByUsername(String username) {
		
		Criteria criteria = getCurrentSession().createCriteria(UserDetail.class);
		if(isNotNull(username)){
			criteria.add(Restrictions.eq("username", username));
		}
		
		/*
		List<UserDetail> list = getCurrentSession().createQuery("FROM UserDetail u WHERE u.username = ?")
				.setParameter(0, username).list();

		if (list.size() > 0) {
			return list.get(0);
		}
		*/
				
		List<UserDetail> results = criteria.list();
		if(results.size() > 0){
			return results.get(0);
		}
		
		return null;
		
	}

	public List<UserDetail> findUserDetails(UserGroup userGroup, String keyword) {		
					
		Criteria criteria = getCurrentSession().createCriteria(UserDetail.class);
		
		if(isNotNull(userGroup)){
			criteria.add(Restrictions.eq("userGroup", userGroup));
		}
		
		if(isNotNull(keyword)){
			StringBuilder sbKey = new StringBuilder();
			sbKey.append("%");
			sbKey.append(keyword);
			sbKey.append("%");
			String key = sbKey.toString();
			
			Disjunction or = Restrictions.disjunction();
			or.add(Restrictions.like("username", key));
			or.add(Restrictions.like("firstname", key));
			or.add(Restrictions.like("lastname", key));
			or.add(Restrictions.like("nickname", key));
			or.add(Restrictions.like("email", key));
			or.add(Restrictions.like("phone", key));
			
			criteria.add(or);
		}
		
		@SuppressWarnings("unchecked")
		List<UserDetail> results = criteria.list();		
		return results;
	}
	

	public List<UserDetail> findUserDetails(List<UserGroup> userGroups){
		
		Criteria criteria = getCurrentSession().createCriteria(UserDetail.class);
		criteria.createAlias("userGroups", "ug");
		
		Conjunction con = Restrictions.conjunction();
		Iterator<UserGroup> iter = userGroups.iterator();
		while(iter.hasNext()){
			UserGroup userGroup = iter.next();
			Criterion tmp = Restrictions.eq("ug.userGroupId", userGroup.getUserGroupId());
			con.add(tmp);
		}
		criteria.add(con);

		@SuppressWarnings("unchecked")
		List<UserDetail> results = criteria.list();		
		return results;
	}
	
	public List<UserDetail> findUserDetailsNotInGroup(List<UserGroup> userGroups, String keyword) {
		
		
		Criteria criteria = getCurrentSession().createCriteria(UserDetail.class);
				
		criteria.createAlias("userGroups", "ug");
		
		Conjunction con = Restrictions.conjunction();
		Iterator<UserGroup> iter = userGroups.iterator();
		while(iter.hasNext()){
			UserGroup userGroup = iter.next();
			Criterion tmp = Restrictions.ne("ug.userGroupId", userGroup.getUserGroupId());
			con.add(tmp);
		}
		criteria.add(con);
		
		
		if(isNotNull(keyword)){
			StringBuilder sbKey = new StringBuilder();
			sbKey.append("%");
			sbKey.append(keyword);
			sbKey.append("%");
			String key = sbKey.toString();
			
			Disjunction or = Restrictions.disjunction();
			or.add(Restrictions.like("username", key));
			or.add(Restrictions.like("firstname", key));
			or.add(Restrictions.like("lastname", key));
			or.add(Restrictions.like("nickname", key));
			or.add(Restrictions.like("email", key));
			or.add(Restrictions.like("phone", key));
			
			criteria.add(or);
		}
		
		@SuppressWarnings("unchecked")
		List<UserDetail> results = criteria.list();		
		return results;
/*		
		StringBuilder sbGroupName = new StringBuilder();
		sbGroupName.append("%");
		sbGroupName.append(groupName);
		sbGroupName.append("%");
		
		
		Criteria criteria = getCurrentSession().createCriteria(UserDetail.class, "ud");
		//criteria.createAlias("userdetail_usergroup", "udg", JoinType.INNER_JOIN);
		criteria.createAlias("ud.usergroup", "ug", JoinType.INNER_JOIN);
		//criteria.add(Restrictions.eq("ud.userdetail_id", "udg.userdetail_id"));
		//criteria.add(Restrictions.eq("ug.usergroup_id", "udg.usergroup_id"));
		criteria.add(Restrictions.not(Restrictions.ilike("ug.groupName", sbGroupName.toString())));
		criteria.add(Restrictions.not(Restrictions.ilike("ug.decription", sbGroupName.toString())));
		  
		logger.info(criteria.toString());
		@SuppressWarnings("unchecked")
		List<UserDetail> results = criteria.list();	

		
		StringBuilder sbSql = new StringBuilder();
		//sbSql.append("select ud ");
		sbSql.append("from userdetail ud ");
		//sbSql.append("join USERDETAIL_USERGROUP udg ");
		//sbSql.append("on udg.USERDETAIL_ID = ud.USERDETAIL_ID ");
		sbSql.append("inner join ud.usergroup ug ");
		//sbSql.append("on udg.USERGROUP_ID = ug.USERGROUP_ID ");
		sbSql.append("where ug.groupName not like :groupName ");
		//sbSql.append(groupName);
		//sbSql.append("%' ");
		sbSql.append("and ug.description not like :groupName ");
		//sbSql.append(groupName);
		//sbSql.append("%'");
		
		Query query = getCurrentSession().createQuery(sbSql.toString());
		query.setParameter("groupName", groupName);
		
		
		List<UserDetail> results = query.list();
			
		return results;
*/			
		
	}
}
